#include "soft_i2c.h"

static unsigned char addr = 0;

//IIC����
void iic_SCL_config(void)
{
	GPIO_InitTypeDef gpio_initStruct = {0};
	__HAL_RCC_GPIOB_CLK_ENABLE();
	gpio_initStruct.Mode = GPIO_MODE_OUTPUT_PP;
	gpio_initStruct.Pin = SOFT_IIC_SCL_PIN;
	gpio_initStruct.Speed = GPIO_SPEED_FREQ_LOW;
	gpio_initStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(SOFT_IIC_SCL_PORT,&gpio_initStruct);
}

void iic_SDA_config(SDA_MODE mode)
{
	GPIO_InitTypeDef gpio_initStruct = {0};
	__HAL_RCC_GPIOA_CLK_ENABLE();
	if (SDA_IN == mode)gpio_initStruct.Mode = GPIO_MODE_INPUT;
	else gpio_initStruct.Mode = GPIO_MODE_OUTPUT_PP;
	gpio_initStruct.Pin = SOFT_IIC_SDA_PIN;
	gpio_initStruct.Speed = GPIO_SPEED_FREQ_LOW;
	gpio_initStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(SOFT_IIC_SDA_PORT,&gpio_initStruct);
}

//IIC��ʼ��
void iic_init(void)
{
	iic_SCL_config();
	iic_SDA_config(SDA_OUT);
	IIC_SCL_H;
	IIC_SDA_H;
	delay_us(2);
}

//IIC��ʼ����
void iic_start(void)
{
	iic_SDA_config(SDA_OUT);
	IIC_SDA_H;
	IIC_SCL_H;
	delay_us(4);
	IIC_SDA_L;
	delay_us(4);
	IIC_SCL_L;
	delay_us(2);
}

//IICӦ��
void iic_ack(void)
{
	iic_SDA_config(SDA_OUT);
	IIC_SCL_L;
	delay_us(2);
	IIC_SDA_L;
	delay_us(2);
	IIC_SCL_H;
	delay_us(2);
	IIC_SCL_L;
}

//IIC��ֹ����
void iic_stop(void)
{
	iic_SDA_config(SDA_OUT);
	IIC_SCL_L;
	IIC_SDA_L;
	delay_us(2);
	IIC_SCL_H;
	delay_us(2);
	IIC_SDA_H;
	delay_us(2);
}

//IIC�ȴ�Ӧ��
unsigned char iic_waitAck(void)
{
	unsigned short i = 0;
	iic_SDA_config(SDA_OUT);
	IIC_SCL_L;
	delay_us(2);
	IIC_SDA_H;
	delay_us(2);
	IIC_SCL_H;
	iic_SDA_config(SDA_IN);
	while(HAL_GPIO_ReadPin(SOFT_IIC_SDA_PORT,SOFT_IIC_SDA_PIN))
	{
		if ((i++) > 200)
		{
			iic_stop();
			return 1;
		}
	}
	IIC_SCL_L;
	return 0;
}

//IIC��Ӧ��
void iic_nack(void)
{
	iic_SDA_config(SDA_OUT);
	IIC_SCL_L;
	delay_us(2);
	IIC_SDA_H;
	delay_us(2);
	IIC_SCL_H;
	delay_us(2);
	IIC_SCL_L;
	delay_us(2);
}

//IIC����һ���ֽ�
void iic_sendByte(unsigned char data)
{
	signed char i = 0;
	for (i = 7 ; i >= 0 ; i--)
	{
		if (data >> i) IIC_SDA_H;
		else IIC_SDA_L;
		delay_us(2);
		IIC_SCL_H;
		delay_us(2);
		IIC_SCL_L;
	}
	IIC_SDA_H;//�ͷ�����
	delay_us(2);
}

//IIC��ȡһ���ֽ�
unsigned char iic_readByte(void)
{
	unsigned char temp = 0;
	int i = 0;
	iic_SDA_config(SDA_IN);
	for (i = 0 ; i < 8; i ++)
	{
		IIC_SCL_H;
		delay_us(2);
		temp <<= 1;  // 先左移，再读取（修正顺序）
		temp |= HAL_GPIO_ReadPin(SOFT_IIC_SDA_PORT,SOFT_IIC_SDA_PIN);
		delay_us(2);
		IIC_SCL_L;
	}
	return temp;
}

//IIC��ȡ����ֽ�
unsigned char iic_readMutiBytes(unsigned char reg_address,unsigned char * pDataBuf,unsigned char len)
{
	unsigned char i = 0;
	iic_start();
	iic_sendByte((unsigned char)ADDR_W);
	if (iic_waitAck()) return 1;
	iic_sendByte(reg_address);
	if (iic_waitAck()) return 1;

	iic_start();
	iic_sendByte((unsigned char)ADDR_R);
	if (iic_waitAck()) return 1;
	for( i = 0; i < len ; i++)
	{
		pDataBuf[i] = iic_readByte();
		if (len - 1 == i) iic_nack();
		else iic_ack();
	}
	iic_stop();
	return 0;
}

//IICд��һ���ֽ�
unsigned char iic_sendMutiBytes(unsigned char reg_address,unsigned char * pDataBuf,unsigned char len)
{
	unsigned char i = 0;

	iic_start();

	iic_sendByte((unsigned char)ADDR_W);
	if (iic_waitAck())return 1;

	iic_sendByte(reg_address);
	if (iic_waitAck())return 1;

	for ( i = 0 ; i < len ; i++)
	{
		iic_sendByte(pDataBuf[i]);
		if (iic_waitAck()) return 1;
	}
	iic_stop();
	return 0;
}

//IIC��ȡһ���ֽ�
unsigned char iic_readSingelByte(unsigned char reg_address,unsigned char * pData)
{
	//unsigned char i = 0;
	iic_start();
	iic_sendByte((unsigned char)ADDR_W);
	if (iic_waitAck()) return 1;
	iic_sendByte(reg_address);
	if (iic_waitAck()) return 1;

	iic_start();
	iic_sendByte((unsigned char)ADDR_R);
	if (iic_waitAck()) return 1;

	*pData = iic_readByte();
	iic_nack();

	iic_stop();
	return 0;
}

//iic����һ���ֽ�����
unsigned char iic_sendSingleByte(unsigned char reg_address,unsigned char pData)
{
	iic_start();

	iic_sendByte((unsigned char)ADDR_W);
	if (iic_waitAck())return 1;

	iic_sendByte(reg_address);
	if (iic_waitAck())return 1;

	iic_sendByte(pData);
	if (iic_waitAck()) return 1;

	iic_stop();
	return 0;
}
